/*****************************************************************************/
/*                        >>> func_PCNIPC.c -- <<<                           */
/*	Trabajo Practico 2do. cuatrimestre 2011                                  */
/*	TP:"FUSELAJE"                                                            */
/*	GRUPO: Reduce Fat Fast                                                   */
/*	INTEGRANTES: Emanuel Genovese                                            */
/*               Federico Gabriel Garcia                                     */
/*               Federico Pioli                                              */
/*               Esther Insfrain                                             */
/*               Luciano Bagattin                                            */
/*	Fecha UM:                                                                */
/*****************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include "../headers/func_PCNIPC.h"
#include "../headers/constantes.h"
#include "func_strings.h"
#include "constants_commons.h"
#include "func_ipc.h"

/******************************************************************************/
/* Nombre de Funcion: fSendIPCCXsocket                                        */
/* Parametros: socket: socket por el cual se comunica                         */
/*             st: estructura que parseara para enviarlo a otros procesos     */
/*             log: archivo de log                                            */
/* Descripcion: Funcion que envia al Ppd la posicion del cabezal              */
/******************************************************************************/

int fSendIPCCXsocket(int iSocket, stNIPC st, void * sPayload, t_log * log) {
	/*declaracion de variables locales*/

	int iOperados = -11, fEnvio_OK = 0;
	t_stream *t;
	char stcadena[1024] = "\0";

	if (strcmp(st.sDescriptorOriginal, "NULL") == 0) {
		memcpy(st.sDescriptorOriginal, (char*) fGenerar_Desc_ID(), 16);
	} //fin del if

	sprintf(stcadena, "%s%d%d%s%d", "envio", st.sPayload_lenth, st.iType,
			st.sDescriptorOriginal, st.iPayloadDescriptor);
	puts(stcadena);
	switch (st.iPayloadDescriptor) {
	case POSICIONCABEZAL:
		sPayload = NULL;

		t = stNIPC_serializer(&st, sPayload, NULL);

		break;
	case LECTURA:case TRACE:

		t = stNIPC_serializer(&st, sPayload, stPLecturaSector_serializer);
		break;
	case ESCRITURA:
		t = stNIPC_serializer(&st, sPayload, stPEscrituraSector_serializer);
		break;

	}
	/*Serializacion de la estructura de envio*/

	/*fin de la declaracion de variables locales*/

	if (iSocket != -1) {

		while (fEnvio_OK == 0) {

			if ((iOperados = send(iSocket, t->data, t->length, 0)) == -1) {

				fEnvio_OK = 2;

			}
			if (t->length == iOperados) {
				fEnvio_OK = 1;

			}
			if (iOperados == 0)
				fEnvio_OK = 2;
		} //fin del while

		if (fEnvio_OK == 2) {
			iOperados = -1;
			puts("mando mal");
		}
	} //fin del if

	return (iOperados == -1) ? 0 : iOperados;
} //fin del fSendIPCCXsocket

/******************************************************************************/
/* Nombre de Funcion: fRecvIPCCXsocket                                        */
/* Parametros: socket: socket por el cual se comunica                         */
/*             stR: estructura donde parseara todo lo qeu le envia el PPD     */
/*               log: archivo de log                                          */
/* Descripcion: Funcion que envia al Ppd la posicion del cabezal              */
/******************************************************************************/

int fRecvIPCCXsocket(int iSocket, stNIPC *stR, void ** sPayload1, t_log * log) {
	/*declaracion de variables locales*/
	char *cadHeader = NULL;
	char *cadPayload = NULL;
	vecTrace*sP = NULL;
	vecTrace spV;
	char stcadena[1024] = "\0";
	int iVariable;
	stREscrituraSector *sPRE = NULL;
	stREscrituraSector stRE;
	stRLecturaSector *stPE;
	stRLecturaSector stP;
	stTrace *stT = NULL;
	stTrace stTpointer;

	int iMaxBuffer, iOperados, iFlag;
	t_stream * p = (t_stream *) malloc(sizeof(t_stream));
	t_stream * q = (t_stream *) malloc(sizeof(t_stream));

	/*fin de la declaracion de variables locales*/

	cadHeader = (char *) malloc(sizeof(stNIPC));
	iMaxBuffer = sizeof(stNIPC);

	while ((iOperados = recv(iSocket, cadHeader, iMaxBuffer, MSG_PEEK))
			== iMaxBuffer) {
		iMaxBuffer += 512;
		cadHeader = realloc(cadHeader, iMaxBuffer);

	} //fin del while

	iOperados = recv(iSocket, cadHeader, iMaxBuffer, 0);

	if ((iOperados == -1) || (iOperados == 0)) {
		log_error(log, NOMBREPROCESO, "Message error: %s",
				"Error en el recv del header de la estructura NIPC del PPD");

		iFlag = 0;
		iOperados = -1;
	} //fin del if

	log_info(log, NOMBREPROCESO, "Message info: %s",
			"Exito  en el recv del header de la estructura NIPC del PPD");

	p->data = cadHeader;
	p->length = iOperados;

	stNIPC_deserializer(p, stR);

	if (stR->sPayload_lenth > 0) {

		cadPayload = (char*) malloc(stR->sPayload_lenth);

		memcpy(cadPayload, cadHeader + 26, stR->sPayload_lenth);

		iFlag = 1;
		q->data = cadPayload;
		q->length = stR->sPayload_lenth;
		sprintf(stcadena, "%d%d%s%d", stR->iPayloadDescriptor, stR->iType,
				stR->sDescriptorOriginal, stR->sPayload_lenth);

		puts(stcadena);
	}
	if (iFlag) {

		switch (stR->iPayloadDescriptor) {

		case POSICIONCABEZAL:

			stPosCabezal_deserializer(q, &sP);
			memset(stcadena, '\0', 1024);
			spV = *sP;

			*sPayload1 = &spV;

			break;
		case ESCRITURA:
			stREscrituraSector_deserializer(q, &sPRE);
			stRE = *sPRE;
			*sPayload1 = &stRE;
			break;
		case LECTURA:

			stRLecturaSector_deserializer(q, &stPE);
			stP = *stPE;
			*sPayload1 = &stP;
			break;
		case TRACE:
			stTrace_deserializer(q, &stT);
			stTpointer = *stT;
			*sPayload1 = &stTpointer;
			break;

		} //fin del switch

	} //fin del if

	return (iOperados == -1) ? 0 : iOperados;
} //fin del fRecvIPCCXsocket
